package com.zhanpple.color_picker.library

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View

/**
 * @author zhangmingping
 * @date 2022/2/22 11:04 上午
 * des:S饱和度、V明度选择器
 */
class ColorSVPicker @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
    private val mPaint = Paint(Paint.ANTI_ALIAS_FLAG)
    private val mPointPaint = Paint(Paint.ANTI_ALIAS_FLAG)

    private var mFloatArray = FloatArray(3)

    private val mRadius by lazy {
        ScreenSizeUtils.dp2px(10F, resources)
    }

    private val mShapePadding by lazy {
        ScreenSizeUtils.dp2px(10F, resources)
    }

    private var mColor: Int = Color.RED

    /**
     * 设置色调
     * @param hue 色调
     */
    fun setColorHue(hue: Float, back: Boolean = true) {
        mFloatArray[0] = hue
        mColor = Color.HSVToColor(floatArrayOf(hue, 1F, 1F))
        setColorShader()
        invalidate()
        if (back) {
            mColorBack?.invoke(Color.HSVToColor(mFloatArray))
        }
    }

    /**
     * 设置颜色
     * @param color 颜色
     */
    fun setCurrentColor(color: Int, back: Boolean = true) {
        Color.colorToHSV(color, mFloatArray)
        setColorHue(mFloatArray[0], back)
    }

    private var mDx = 0F
    private var mDy = 0F
    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        mDx = measuredWidth - mShapePadding * 2
        mDy = measuredHeight - mShapePadding * 2
        setColorShader()
    }

    private fun setColorShader() {
        val linearShader = LinearGradient(
            mShapePadding,
            mShapePadding,
            measuredWidth.toFloat() - mShapePadding,
            mShapePadding,
            intArrayOf(Color.WHITE, mColor),
            null,
            Shader.TileMode.CLAMP
        )

        val linearShader2 = LinearGradient(
            mShapePadding,
            mShapePadding,
            mShapePadding,
            measuredHeight.toFloat() - mShapePadding,
            intArrayOf(Color.WHITE, Color.BLACK),
            null,
            Shader.TileMode.CLAMP
        )
        val composeShader = ComposeShader(linearShader, linearShader2, PorterDuff.Mode.MULTIPLY)
        mPaint.shader = composeShader
        postInvalidate()
    }

    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(event: MotionEvent): Boolean {
        val x = event.x - mShapePadding
        val y = event.y - mShapePadding

        mFloatArray[1] = (x / mDx).coerceAtMost(1F).coerceAtLeast(0F)
        mFloatArray[2] = (1F - y / mDy).coerceAtMost(1F).coerceAtLeast(0F)
        mColorBack?.invoke(Color.HSVToColor(mFloatArray))
        invalidate()
        return true
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        canvas?.drawRect(0F, 0F, measuredWidth.toFloat(), measuredHeight.toFloat(), mPaint)

        mPointPaint.color = Color.BLACK
        canvas?.drawCircle(
            mFloatArray[1] * mDx + mShapePadding,
            (1F - mFloatArray[2]) * mDy + mShapePadding,
            mRadius,
            mPointPaint
        )
        mPointPaint.color = Color.WHITE
        canvas?.drawCircle(
            mFloatArray[1] * mDx + mShapePadding,
            (1F - mFloatArray[2]) * mDy + mShapePadding,
            mRadius * 0.8F,
            mPointPaint
        )
    }

    var mColorBack: ((Int) -> Unit)? = null

    init {
        setLayerType(LAYER_TYPE_SOFTWARE, null)
        Color.colorToHSV(mColor, mFloatArray)
    }
}